perm filename ILISP.MAN[RUT,LSP] blob
sn#380273 filedate 1978-09-12 generic text, type T, neo UTF8
RUTGERS/UCI LISP MANUAL
Rick LeFaivre
Computer Science Department
Rutgers University
October 8, 1977
RUTGERS/UCI LISP MANUAL Page 2
CONTENTS
←←←←←←←←
I. INTRODUCTION . . . . . . . . . . . . . . . . . . . . . 4
Documentation Conventions . . . . . . . . . . . . . . 4
II. USER INTERACTION . . . . . . . . . . . . . . . . . . . 5
Terminal Interrupts . . . . . . . . . . . . . . . . . 5
Terminal Input . . . . . . . . . . . . . . . . . . . 6
Lower-Case Characters . . . . . . . . . . . . . . . . 7
Defining New Functions . . . . . . . . . . . . . . . 7
Default Function Names . . . . . . . . . . . . . . . 7
Expansion of Core . . . . . . . . . . . . . . . . . . 8
Exiting from LISP . . . . . . . . . . . . . . . . . . 8
System-Monitoring Functions . . . . . . . . . . . . . 9
III. NEW LANGUAGE FACILITIES . . . . . . . . . . . . . . . . 10
The New NIL . . . . . . . . . . . . . . . . . . . . . 10
ATOM, CONSP, and PATOM . . . . . . . . . . . . . . . 10
Funargs and SPDL Pointers . . . . . . . . . . . . . . 10
Functions for Controlling Evaluation . . . . . . . . 10
Functions for Manipulating Property Lists . . . . . . 12
New Mapping Functions . . . . . . . . . . . . . . . . 13
New List-Manipulation Functions . . . . . . . . . . . 14
New Functions on Strings . . . . . . . . . . . . . . 16
IV. NEW I/O FACILITIES . . . . . . . . . . . . . . . . . . 17
The Octal Point "Q" . . . . . . . . . . . . . . . . . 17
36-Bit Integers . . . . . . . . . . . . . . . . . . . 17
String Input . . . . . . . . . . . . . . . . . . . . 17
Changes to DSKIN/DSKOUT . . . . . . . . . . . . . . . 18
Additions to MODCHR . . . . . . . . . . . . . . . . . 18
New File-Accessing Functions . . . . . . . . . . . . 18
New Output Functions . . . . . . . . . . . . . . . . 20
New Input Functions . . . . . . . . . . . . . . . . . 22
V. NEW DEBUGGING FACILITIES . . . . . . . . . . . . . . . 23
Additions to the Editor . . . . . . . . . . . . . . . 23
Additions to the Break Package . . . . . . . . . . . 23
VI. THE LISP PRETTYPRINTER . . . . . . . . . . . . . . . . 25
Basic Functions . . . . . . . . . . . . . . . . . . . 25
PRETTYPROPS . . . . . . . . . . . . . . . . . . . . . 26
Prettyprint Commands . . . . . . . . . . . . . . . . 26
Printmacros . . . . . . . . . . . . . . . . . . . . . 27
Comments . . . . . . . . . . . . . . . . . . . . . . 29
RUTGERS/UCI LISP MANUAL Page 3
VII. THE COMPILER AND LAP . . . . . . . . . . . . . . . . . 31
Declarations . . . . . . . . . . . . . . . . . . . . 31
Extensions to NOCALL . . . . . . . . . . . . . . . . 32
In-Line Code . . . . . . . . . . . . . . . . . . . . 33
Other Extensions . . . . . . . . . . . . . . . . . . 34
VIII. INFORMATION FOR THE SYSTEM BUILDER . . . . . . . . . . 35
User Error Handling . . . . . . . . . . . . . . . . . 35
Creating One's Own System . . . . . . . . . . . . . . 35
Building ILISP . . . . . . . . . . . . . . . . . . . 36
INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
RUTGERS/UCI LISP MANUAL Page 4
I. INTRODUCTION
←←←←←←←←←←←←←←←
This manual describes ILISP, an extended version of
UCI LISP, which is itself an extended version of Stanford
LISP 1.6. The existing documentation for ILISP is spread over
three documents, reflecting the various stages in the development
of the system:
(1) SAILSP.MAN Describes the basic LISP 1.6 upon which
UCI LISP is based.
(2) UCILSP.MAN Describes the modifications and
additions contained in the UCI LISP
system as available from UC-Irvine.
(3) ILISP.MAN (This document). Describes the
modifications and additions contained
in the ILISP system as available from
Rutgers.
We assume here that the reader is familiar with the UCI LISP
system as described in (1) and (2) above - this document
describes only the Rutgers modifications and additions. Note
that there are numerous minor modifications and corrections to
UCI LISP which have no direct user impact, and thus are not
described in this manual. The interested LISP maintainer is
referred to the various source listings for detailed information.
Document Conventions
←←←←←←←←←←←←←←←←←←←←
In this manual arguments to functions are represented as
meta-linguistic variables of the form <variable>. Each function
is presented as a template, with arguments which will be
evaluated indicated by preceding them with "@". For example,
(SETQ <atom> @<value>)
indicates that <atom> is not evaluated and <value> is. Arguments
which are optional are indicated by enclosing them in braces,
e.g., {<x>}, and an unlimited number of arguments is indicated by
ellipses (. . .).
RUTGERS/UCI LISP MANUAL Page 5
II. USER INTERACTION
←←←←←←←←←←←←←←←←←←←←
The ILISP system is started by typing
.R ILISP
at monitor level. The compiler is called ILISPC, and may be run
via
.R ILISPC
(see section VII for details on the compiler). The system also
comes with ILISP versions of the AI languages MICRO-PLANNER
(.R PLNR), CONNIVER (.R CNVR), and FUZZY (.R FUZZY).
Terminal Interrupts
←←←←←←←←←←←←←←←←←←←
One of the major advantages of ILISP over UCI LISP and
LISP 1.6 is the presence of a terminal interrupt-handling
facility. The interrupt routine is entered by striking a single
↑C (Control-C) if awaiting terminal input, or two consecutive
↑C's if computing. The interrupt routine types:
Interrupt (Help=?):
and awaits an interrupt character from the user. Typing "?" will
produce the following list of choices:
CR = Continue (Ignore ↑C)
↑D = Return to Top Level
↑X = Exit to Monitor via (%$EXIT NIL)
↑H = Break Next Fn Call
↑B = Back Up and Break Last Fn Call
↑G = (ERR @ERRORX)
↑E = (ERR NIL)
↑R = Restore System OBLIST
Typing a carriage return causes ILISP to continue doing whatever
it was doing when the ↑C was typed. ↑H, ↑B, ↑G, ↑E, and ↑R are
as described in the UCI LISP manual under the ↑C REENTER
procedure (which is now obsolete). ↑D causes an immediate return
to the top level of LISP, and ↑X causes an exit to the monitor
(see EXIT). A subsequent CONTINUE at monitor level will cause
ILISP to continue where it left off, while START or REENTER will
cause it to restart at the top level (like ↑D). Any other
character is ignored by the interrupt routine. The system is
fully protected against a ↑C interrupt occuring at the wrong
time; for example, if ↑C is typed during a garbage collection
the garbage collection is completed before the interrupt is
recognized (however, if several interrupts occur during a single
garbage collection, it will be aborted). If the LOADER is in
core when ↑C is struck, the LOAD will be aborted and ILISP will
be restored to its state before the LOAD was invoked.
RUTGERS/UCI LISP MANUAL Page 6
Note that a START or REENTER at monitor level will restart
ILISP at the top level only if the system was exited normally
(via ↑C ↑X or EXIT). If ILISP was somehow exited without going
through the normal exit procedure, START or REENTER will cause
the ↑C interrupt routine to be entered.
Terminal Input
←←←←←←←←←←←←←←
In addition to the above interrupt characters, which are
recognized after a ↑C interrupt, there are three special control
characters which are active during terminal input.
As before, ↑G causes an (ERR @ERRORX) to occur, returning
either to an (ERRSET <x> ERRORX) if present or to the top level.
Recall that this character may be changed via
(ERRCH @<char>)
where <char> is the ASCII value of the new character. ERRCH
returns the ASCII value of the old error character.
Two new control characters affect the handling of errors
during terminal input. If the error is in the current line, the
system line-editing features may of course be used (RUBOUT/DELETE
or ↑H to delete a character, ↑U to delete the line, ↑R to retype
the line). In standard UCI LISP, if an error was noticed after
carriage return was struck, the user was forced to abort the
entire procedure via ↑G. ILISP now provides a "reread character"
↑Z which causes READ to ignore what was typed previously and
start over. The reread character may be changed via
(REREADCH @<char>)
which is similar to ERRCH in its operation.
Occasionally an error is not discovered until a good deal of
typing has taken place. Rather than starting over, an "edit
character" ↑F (for "fix") is also provided which causes the LISP
editor to be called when the expression is completely entered (↑F
may be typed at any point within the expression). The user may
then correct the expression, returning the edited version as the
value of the READ when OK is typed. The edit character may be
changed via
(EDITCH @<char>)
which is similar to ERRCH and REREADCH.
RUTGERS/UCI LISP MANUAL Page 7
Lower-Case Characters
←←←←←←←←←←←←←←←←←←←←←
ILISP normally considers lower-case letters to be distinct
from their upper-case counterparts. Thus, for example, nil and
NIL represent different atomic symbols. If this is undesirable,
the new RAISE function may be used to modify the handling of
lower-case letters.
(RAISE @<flag>)
instructs READ to convert lower-case letters to upper case
(<flag>=T) or pass them through unchanged (<flag>=NIL, the
default setting). Note that (RAISE T) applies only to non-string
atomic symbols read via READ; lower-case letters in strings, and
those read via READCH or TYI, will not be converted to upper
case. Note also that since character echoing is performed at the
monitor level, all lower-case letters will be echoed as lower
case independant of the RAISE function. RAISE returns the
previous value of <flag>.
Defining New Functions
←←←←←←←←←←←←←←←←←←←←←←
The name of each function defined via DE, DF, or DM, or
edited via EDITF, is now kept on the list ALLFNS. This list may
be consulted after a long terminal session to see what functions
have been created or modified and must therefore be saved before
exiting.
If an existing function is redefined via DE, DF, or DM, the
old definition is now saved on the property list of the function
name under the property UNSAVE. The old definition may be
restored via
(UNSAVE <name>)
if desired. The saving of old definitions may be disabled by
setting UNSAVE to NIL (it is initially T).
Default Function Names
←←←←←←←←←←←←←←←←←←←←←←
DE, DF, and DM now set LASTWORD to the name of the function
just defined. The value of LASTWORD is used as a default name by
the editor, the prettyprinter, and the break package when no
function name is given explicitly. DE, DF, DM, EDITF, EDITV,
EDITP, PP, BREAK, and TRACE all set LASTWORD, and all but DE, DF,
and DM use it when no argument is given. A newly-defined
function may thus be prettyprinted via (PP), broken or traced via
(BREAK) or (TRACE), and edited via (EDITF), all without retyping
the function name.
RUTGERS/UCI LISP MANUAL Page 8
Expansion of Core
←←←←←←←←←←←←←←←←←
If ILISP is started with its low segment expanded beyond its
normal limit, the initial allocation procedure is entered as
before. However, it is recommended that one of the following new
functions be used to expand core without leaving LISP:
(REALLOC @<fws> @<bps> @<rpdl> @<spdl> @<fs>)
REALLOC's arguments specify increments (in words) to be
added to each of the five major allocation areas:
fullword space, binary program space, the regular
pushdown list, the special pushdown list, and free
storage (i.e., list space). After expanding core as
necessary and reallocating storage, REALLOC returns
control directly to the top level of LISP. In order to
retain control, the user must set up an INITFN which will
be called after REALLOC returns.
(EXPFWS @<fws>)
For those of us who can't remember the order of the
arguments to REALLOC, EXPFWS is equivalent to:
(REALLOC @<fws> 0 0 0 0)
(EXPBPS @<bps>)
Equivalent to (REALLOC 0 @<bps> 0 0 0).
(EXPFS @<fs>)
Equivalent to (REALLOC 0 0 0 0 @<fs>).
Exiting from LISP
←←←←←←←←←←←←←←←←←
(EXIT @<flag>)
ILISP may be exited via the EXIT function. <flag>
specifies whether ILISP's sharable high segment should be
deleted (<flag>=NIL) or retained (<flag>=T) before
exiting. There is normally no reason to retain the high
segment, as it is automatically loaded when ILISP is
STARTed or CONTinued. By deleting the high segment, EXIT
allows the user to exit from LISP and save the low
segment as a runnable SAV file - when the file is later
RUN, ILISP's sharable high segment will be loaded
automatically. (Note that an EXCISE or SYSCLR should be
performed before exiting if the low segment is to be
saved - see section VIII for more details). (EXIT T) is
necessary only after SETSYS has been used to create a new
sharable system, when both the low and high segments must
be saved. At the top level, (EXIT) (and ↑C ↑X) are
equivalent to (EXIT NIL).
RUTGERS/UCI LISP MANUAL Page 9
System-Monitoring Functions
←←←←←←←←←←←←←←←←←←←←←←←←←←←
(FSCNT)
Returns the length of the free storage list, i.e., the
number of available cons cells.
(FWCNT)
Returns the length of the fullword list.
(DTIME)
Returns the time of day in milliseconds past midnight.
(DATE)
Returns the current date as a list of the form:
(<month> <day> <year-1900>)
(TIMER {<expr1>} {<expr2>} . . .)
TIMER serves as either an evaluation timer or an
incremental timer. If any arguments are present they are
evaluated, the execution time, portion of that time spent
garbage collecting, elapsed clock time, and number of
conses are printed, and the value of the last expression
is returned. For example, (TIMER (GC) (GC)) times two
garbage collections, printing the message:
627. msec CPU (627. msec GC), 1300. msec clock, 0. conses
If TIMER is called with no arguments (i.e., (TIMER)), the
execution time, etc., since the last evaluation of
(TIMER) are printed and a value of NIL is returned. The
intent here is that TIMER will be called once to
initialize it, a number of expressions will be evaluated,
and then TIMER will be called again to check the
incremental statistics. Note that TIMER performs a TALK
before printing these statistics, so they will appear on
the terminal even if a ↑O has been struck.
RUTGERS/UCI LISP MANUAL Page 10
III. NEW LANGUAGE FACILITIES
←←←←←←←←←←←←←←←←←←←←←←←←←←←←
The New NIL
←←←←←←←←←←←
In keeping with its character as both an atom and the
representation of the empty list, the atom NIL has been modified
so that its CAR and CDR are both NIL. One can now, for example,
pick up the arguments to an FEXPR via a sequence of CAR/CDR
combinations, with missing arguments automatically set to NIL.
Note that NIL now has a usable property list, although it is not
stored as the CDR of NIL as with other atoms (GET, PUTPROP, etc.
are all aware of its actual location).
ATOM, CONSP, and PATOM
←←←←←←←←←←←←←←←←←←←←←←
ATOM has been fixed to return T only for a true LISP atom
(i.e., an atomic symbol or a number). It will no longer be true
if its argument is a pointer to some other location which happens
to have -1 in its CAR field. Similarly, CONSP is true only if
its argument is a true LISP consed cell. It is now the case that
(ATOM X), (CONSP X), and (AND (PATOM X) (NOT (ATOM X))) define
three disjoint classes.
Funargs and SPDL Pointers
←←←←←←←←←←←←←←←←←←←←←←←←←
For those of you who use funargs, it should be noted that
this mechanism has now been integrated with UCI LISP SPDL
pointers. A funarg binding context pointer can now be used with
the various stack-accessing functions, and stack pointers may be
used for the optional funarg argument to EVAL and APPLY. Note in
particular that a pointer of zero always refers to the top level,
so that
(EVAL @<expr> 0)
may always be used to evaluate <expr> using the top-level values
of all variables.
Functions for Controlling Evaluation
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
(CATCH <expr> {<label>})
(CATCH <expr> {(<l1> <e11> . . .)} {(<l2> <e21> . . .)} . . .)
(THROW @<value> {<label>})
CATCH and THROW provide a more convenient method of
programming transfers to a higher level in the control
hierarchy than ERRSET/ERR, which (as the names imply)
were originally designed for error handling rather than
planned (programmed) transfers. CATCH simply evaluates
RUTGERS/UCI LISP MANUAL Page 11
<expr>, and if no THROWs are executed during that
evaluation, returns the value of <expr>. If a THROW is
evaluated and the CATCH has no <label> then the CATCH is
immediately exited with <value> as its value (regardless
of whether the THROW had a <label> or not). An unlabeled
CATCH will thus catch a value thrown by any THROW. If
the CATCH has a <label>, it will catch values thrown only
by a THROW with the same label; other THROWs are passed
on in search of a higher-level CATCH with a matching
label. Finally, a single CATCH can catch a variety of
different THROWs via a SELECTQ-like mechanism as shown
above. Each <l> is either a <label> or a list of
<label>s; if a THROW <lable> matches an <l> or a member
of an <l>, the corresponding <e>s are evaluated and the
value of the last one is returned as the value of the
CATCH. If no labels match, the THROW is passed on in
search of a higher level CATCH. Note that a missing
THROW <label> is equivalent to a <label> of NIL, and may
be caught as such. CATCH and THROW are compiled in-line.
(RPTQ @<n> <expr>)
RPTQ evaluates <expr> <n> times, returning the value of
the <n>th evaluation. If <n> is less than one, no
evaluation is done and NIL is returned. Note that the
special variable RPTN is initialized to one, and is
incremented after each evaluation; it may be referenced
within <expr> if desired. For example, the following
prints the squares of the integers from 1 to 20:
(RPTQ 20. (PRINT (*TIMES RPTN RPTN)))
RPTQ is compiled in-line.
(*APPLY @<fn> @<arglist>)
*APPLY has the same relation to APPLY as *EVAL has to
EVAL, i.e., it is a SUBR instead of an LSUBR, and it does
not take the optional funarg argument. APPLYs without
the funarg argument are compiled as *APPLYs.
(DO <e1> {<e2>} . . .)
DO is equivalent to PROGN.
(BOUNDP @<var>)
Returns T if the atomic symbol <var> is currently bound,
NIL otherwise. Note that <var> must have been assigned a
value in the interpreter or as a special variable in
compiled code. Bindings of local variables in compiled
code will not be noticed by BOUNDP.
RUTGERS/UCI LISP MANUAL Page 12
Functions for Manipulating Property Lists
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
(DEFLIST <l> {<defval>} <prop>)
DEFLIST is useful for placing a property on a number of
atomic symbols. <l> should be a list of items, each of
which is either an atomic symbol <a> or a two-element
list (<a> <val>). Each <a> will have a <prop> property
placed on its property list, with a value of <val> if
present, or <defval> if only the atomic symbol was given.
<defval> is optional, with a default value of T assumed.
As an example of the use of DEFLIST, the following will
give TOM and BOB ages of 15, and SAM an age of 20 (i.e.,
the 20 overrides the default value of 15):
(DEFLIST (TOM BOB (SAM 20)) 15 AGE)
(DEFP <at1> <at2> <props>)
DEFP is used to place one of <at2>'s properties onto
<at1>. <props> may be either a single property name or a
list of property names (in which case the first property
in the list found on <at2> is used. For example,
(DEFP DO PROGN FSUBR)
defines DO as an alternative to PROGN. If it is not
known whether PROGN is compiled or not,
(DEFP DO PROGN (FSUBR FEXPR))
may be used instead. DEFP returns <at1> if the property
was found, NIL otherwise.
(DEFV <atom> <value>)
Equivalent to (SETQ <atom> @<value>), except that <value>
is not evaluated and the value returned is <atom> instead
of <value>. DEFV is used by the prettyprinter to print
VALUE properties.
(ADDPROP @<atom> @<value> @<prop>)
ADDPROP is used to collect a number of values under a
single property. If <atom> has no <prop> property,
(LIST @<value>) is placed onto the property list of
<atom>. If <value> is already a member of the <prop>
property of <atom> (which is assumed to be a list), no
action is taken. Otherwise <value> is CONSed onto the
front of the list and it is placed back on the property
list of <atom>. The (modified) list is returned as the
value of ADDPROP. Note that ADDPROP uses ENTER to enter
<value> on the property list, so MEMBFN may be used to
indicate whether MEMB or MEMBER checks should be
performed.
RUTGERS/UCI LISP MANUAL Page 13
(PUTLIST @<l> @<value> @<prop>)
Places <value> as the <prop> property of each element of
<l> (which should be a list of atomic symbols). PUTLIST
returns NIL.
(REMLIST @<l> @<prop>)
Removes the <prop> property from each element of <l>
(which should be a list of atomic symbols). REMLIST
returns NIL.
(REMPROPS @<atom> @<l>)
Treats each element of <l> (a list of atomic symbols) as
a property, removing that property from <atom>. For
example,
(REMPROPS @FUNC @(EXPR FEXPR MACRO))
insures that FUNC is not an uncompiled function.
REMPROPS returns NIL.
(PUT @<atom> @<value> @<prop>)
PUT is equivalent to PUTPROP.
New Mapping Functions
←←←←←←←←←←←←←←←←←←←←←
(MAPATOMS @<fn>)
Applies <fn> (a function of one argument) to every atomic
symbol on the OBLIST and returns NIL. MAPATOMS is
compiled in-line.
(EVERY @<fn> @<l>)
Returns T if <fn> (a function of one argument) is non-NIL
for each element of the list <l>. In other words, <fn>
←←←←
is applied to each element of <l> in turn until either
<fn> returns NIL (in which case EVERY returns NIL), or
<l> is exhausted (with EVERY returning T). For example,
the following checks whether L is a list of atoms:
(EVERY @ATOM L)
EVERY is compiled in-line.
(SOME @<fn> @<l>)
Returns a non-NIL value if <fn> (a function of one
argument) is non-NIL for some element of the list <l>.
←←←←
The value returned is the tail of <l> starting with that
element. SOME is compiled in-line.
RUTGERS/UCI LISP MANUAL Page 14
(NOTEVERY @<fn> @<l>)
Equivalent to (NOT (EVERY @<fn> @<l>)).
(NOTANY @<fn> @<l>)
Equivalent to (NOT (SOME @<fn> @<l>)).
(SUBSET @<fn> @<l>)
Applies <fn> (a function of one argument) to each element
of the list <l>, returning a list consisting of each
element of <l> which causes <fn> to return a non-NIL
value. For example, the following finds all atoms in L:
(SUBSET @ATOM L)
SUBSET is compiled in-line.
New List-Manipulation Functions
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
(*INSERT @<x> @<l> @<comparefn> @<nodups>)
(The insert, merge, and sort functions were copied with
minor modifications from the Carnegie-Mellon University
LISPX package). *INSERT destructively inserts <x> into
the sorted list <l> in the proper slot using <comparefn>
as a binary comparison function.
(<comparefn> @<x> @<y>)
should return a non-NIL value if <x> either precedes <y>
in sorted order or <x> and <y> are equal, and NIL if <y>
precedes <x>. If <comparefn> is NIL, LEXORDER will be
used; if <comparefn> is T, LEXORDERCAR (see below) will
be used. <nodups> controls the handling of duplicate
values: if <nodups> is non-NIL, <x> will not be inserted
into <l> if an element equal to <x> is already present in
<l>. *INSERT performs a binary search to determine where
to insert the new element. The value of *INSERT is the
list <l> with <x> inserted.
(INSERT @<x> @<l>)
Equivalent to (*INSERT @<x> @<l> NIL NIL).
(*MERGE @<l1> @<l2> @<comparefn> @<nodups>)
*MERGE returns a new list which is the merge of the
sorted lists <l1> and <l2>. <comparefn> and <nodups> are
as described under *INSERT, i.e., <comparefn> is the
binary comparison function, and <nodups> controls whether
duplicate elements will be allowed or not.
RUTGERS/UCI LISP MANUAL Page 15
(MERGE @<l1> @<l2>)
Equivalent to (*MERGE @<l1> @<l2> NIL NIL).
(*SORT @<l> @<comparefn> @<nodups>)
*SORT returns a new list which is the sort of the list
<l>, using a binary insertion sort. <comparefn> and
<nodups> are as described under *INSERT, i.e.,
<comparefn> is the binary comparison function, and
<nodups> controls whether duplicate elements will be
removed or not.
(SORT @<l>)
Equivalent to (*SORT @<l> NIL NIL).
(LEXORDERCAR @<x> @<y>)
LEXORDERCAR returns the result of applying LEXORDER to
the CARs of <x> and <y>, i.e., it is a binary comparison
function used for sorting expressions in ascending
lexical order of the CARs of the expressions.
(UNION @<l1> @<l2>)
Returns a list which is the union of the two lists <l1>
and <l2>. If <l1> and <l2> are of unequal length, UNION
is more efficient if <l2> is the longer list. Note that
membership tests are made using MEMBER (and hence EQUAL).
If MEMB (EQ) checks are desired instead, change the value
of MEMBFN from MEMBER to MEMB.
(INTERSECTION @<l1> @<l2>)
Returns a list which is the intersection of <l1> and
<l2>. See comments for UNION concerning efficiency and
MEMBFN.
(ENTER @<value> @<list>)
Returns <list> if <value> is already a member of <list>,
otherwise returns <list> with <value> CONSed onto the
front. As with UNION and INTERSECTION, MEMBFN is used to
indicate whether MEMB or MEMBER checks should be
performed.
(*NCONC @<l1> @<l2>)
*NCONC has the same relation to NCONC as *APPEND has to
APPEND, i.e., it is a SUBR instead of an LSUBR. NCONCs
are compiled as a series of *NCONCs.
RUTGERS/UCI LISP MANUAL Page 16
(NCONC1 @<list> @<value>)
NCONC1 destructively adds <value> to the end of <list>.
Equivalent to
(NCONC @<list> (LIST @<value>))
(ATTACH @<x> @<l>)
ATTACH destructively attachs <x> to the beginning of list
<l>. For example, after
(SETQ L @(A))
(ATTACH @B L)
L has value (B A). If <l> is NIL, ATTACH is equivalent
to CONS.
(MCONS @<x1> @<x2> . . .)
MCONS (Multiple CONS) is a MACRO which expands to
← ←←←←
(CONS @<x1> (CONS @<x2> . . . (CONS @<xn-1> @<xn>)))
It is useful for consing several items onto the list
<xn>.
New Functions on Strings
←←←←←←←←←←←←←←←←←←←←←←←←
(EQSTR @<at1> @<at2>)
Compares the PNAMEs of <at1> and <at2>, returning T if
they are identical and NIL if they differ. Useful for
use with any uninterned atomic symbols (including, of
course, strings).
(SUBSTRING @<str> @<m> @<n>)
Returns a new string consisting of characters <m> through
<n> of <str>. <m> and <n> may be positive integers
(count from left) or negative integers (count from
right). If <m> is non-numeric a value of 1 (first
character) is assumed, and if <n> is non-numeric -1 (last
character) is assumed. Although <str> will typically be
a string, SUBSTRING will actually work with any argument;
←←←
the indicated characters are simply extracted from the
PRINC character string of <str> and formed into a string.
RUTGERS/UCI LISP MANUAL Page 17
IV. NEW I/O FACILITIES
←←←←←←←←←←←←←←←←←←←←←←
The Octal Point "Q"
←←←←←←←←←←←←←←←←←←←
In order to correct the long-standing LISP 1.6/UCI LISP
problem of reading a file which contains numbers which were
printed using a different BASE than the current IBASE, an "octal
point" Q is now printed following numbers when BASE=8. Like the
decimal point (.), the octal point may be turned off by setting
*NOPOINT to T. To summarize the numeric I/O conventions: on
input, any number followed by a "Q" will be interpreted as octal,
any number followed by a "." will be interpreted as decimal, and
all other integers are interpreted according to the current
setting of IBASE; on output, integers will be printed according
to the current value of BASE, with a "Q" (BASE=8) or "."
(BASE=10) appended unless *NOPOINT=T. In order to allow the user
to disable the printing of octal or decimal points when
interacting from the terminal but still have points printed when
dumping to a file (so integers will be read in correctly), DSKOUT
maintains its own copy of *NOPOINT, called *NOPOINTDSK. Both
*NOPOINT and *NOPOINTDSK are initially NIL (i.e., print points),
but either or both may be changed to T if desired.
It should be noted that the lower-case letters "q" and "e"
are now considered equivalent to their upper-case counterparts
when used in numeric input. 10Q and 10q, or 12E and 12e, are now
identical.
36-Bit Integers
←←←←←←←←←←←←←←←
Integers may now be input and output as either signed 35-bit
or unsigned 36-bit numbers. On input, the last 36 bits are
retained (there is no overflow). For example, -1Q and
777777777777Q input as the same quantity. On output, the
decision to print as 36 bits or sign plus 35 bits is under the
control of the variable BASE. If BASE is positive, negative
integers will be printed in standard form (i.e., with a sign).
If BASE is negative, integers will be printed as positive 36-bit
quantities.
String Input
←←←←←←←←←←←←
Recall that strings are normally not interned by the read
routine so that they will be garbage collected when no longer
referenced. If this feature is not desirable, the READ routine
can now be told to intern all strings by setting the special
variable INTERNSTR to T (it is initially NIL). This feature is
used by LAP to uniquely store strings which are referenced from
compiled code.
RUTGERS/UCI LISP MANUAL Page 18
Changes to DSKIN/DSKOUT
←←←←←←←←←←←←←←←←←←←←←←←
If the value of the symbol DSKIN is T (its default value)
then DSKIN prints the value of each non-NIL expression loaded,
attempting to place as many atoms as possible on each line. If
the value of DSKIN is PRINT, the values are printed one per line.
If DSKIN is set to NIL, no printing is done.
Similarly, if the value of DSKOUT is T (its default value),
the name of each function prettyprinted during the DSKOUT is
printed on the terminal so that the user may follow the progress
of the dump. If DSKOUT is set to NIL, no terminal printing is
performed.
The maximum line length used by DSKOUT is stored in
DSKLENGTH, and may be changed if desired (it is initially 80).
The variable LPTLENGTH is equivalent to DSKLENGTH - they may be
used interchangeably.
FILBAK (the file extension used by DSKOUT to back up a file)
has been changed from LBK to QSP to maintain compatability with
the SOS convention of starting backup files with Q (lets one do
things like .DEL *.Q??).
Additions to MODCHR
←←←←←←←←←←←←←←←←←←←
MODCHR now notices when either the "slashifier" (currently
"/") or the comment character (↑Y) is changed and fixes things so
the new characters are used by PRINT. In other words, PRINT will
use the slashifier and comment character most recently defined
via MODCHR. Other special characters (e.g., '.' as the decimal
point) are considered sacred by PRINT, although equivalent
characters may still be defined for READ via MODCHR.
New File-Accessing Functions
←←←←←←←←←←←←←←←←←←←←←←←←←←←←
(GETDEF {<device/directory>} <file> <at1> {<at2>} . . .)
GETDEF is similar to DSKIN, but only one file is accessed
and only selected expressions from that file are read.
In particular, all definitions of each <at> are loaded,
including expressions starting with DEFPROP, DE, DF, DM,
LAP, DEFP, and DEFV (the list of expression types to be
examined is stored as the value of the atom GETDEF, and
may be changed if desired). As usual, <device/directory>
may be omitted, with DSK: assumed. As an example of the
use of GETDEF,
(GETDEF (FUNCS.LSP) FN1 FN2 FN3)
loads any definitions for FN1, FN2, and FN3 found in the
file FUNCS.LSP. The value of each expression loaded is
printed on the terminal for feedback purposes. Note that
RUTGERS/UCI LISP MANUAL Page 19
GETDEF does not intern any new atomic symbols unless
necessary (i.e., unless contained in an expression to be
loaded). Free storage is thus not clogged up with unused
atomic symbols when scanning a large file for
definitions.
(DIRF {<directory>} {<filespec>})
Unlike the function DIR, which returns a list of all the
files in a given directory, DIRF prints the name of each
file in the directory which "matches" <filespec> (it is
thus quite similar in operation to the DIRECT monitor
command). <filespec> may be a dotted pair
(<file>.<ext>), where either <file> and/or <ext> may be *
(match anything), or simply <file>, with (<file>.*)
assumed. Either <directory> or <filespec> or both may be
missing, with the default directory and (*.*) assumed.
As an example of the use of DIRF,
(DIRF (*.LSP))
prints the names of all LSP files in the users directory.
(TYPE {<device/directory>} <file1> {<file2>} . . .)
This function types each <file> on the currently selected
output device. Its principle use is to type a text file
on the terminal without leaving LISP, for example,
(TYPE LSP: (ILISP.MAN))
As usual, <device/directory> may be omitted, with DSK:
assumed. Note that if more than one <file> is given they
are simply concatenated together. Thus TYPE could be
used to create a new file which is the concatenation of
FILE1 and FILE2 by doing the following:
(PROGN (OUTC (OUTPUT T NEWFILE))
(TYPE FILE1 FILE2)
(OUTC NIL))
(%DEVP @<x>)
Returns T if <x> is either a device name (i.e., an atomic
symbol which ends in ":"), or a programmer project number
(i.e, a list whose CDR is not an atomic symbol). Used by
INPUT, OUTPUT, DSKIN, etc.
RUTGERS/UCI LISP MANUAL Page 20
New Output Functions
←←←←←←←←←←←←←←←←←←←←
(MSG <i1> {<i2>} . . .)
MSG provides a general message-printing facility for
ILISP. Each <i> is an instruction which provides a
specific formatting capability:
"<string>" Print <string> using PRINAC
+<number> Space <number> spaces
(T @<n>) Tab to position <n>
T Move to new line
-<number> Print <number> blank lines
(E <expr>) Evaluate <expr>
other Eval and print using PRINA
As an example of the use of MSG, consider the following:
(MSG T "Value of X is:" 5 X T)
which is equivalent to:
(PROGN (TERPRI)
(PRINAC @"Value of X is:")
(SPACES 5)
(PRINA X)
(TERPRI))
Note that MSG prints the desired message on the currently
selected output device. MSG returns NIL, and is compiled
in-line.
(TTYOUT <e1> {<e2>} . . .)
TTYOUT may be used to direct output to the terminal
instead of the currently selected output device. The
current channel is deselected, the TTY is selected, and
the <e>s are evaluated (hopefully doing some printing).
The previous channel is then reselected, and the value of
<en> is returned as the value of the TTYOUT. TTYOUT is
compiled in-line.
(TTYMSG <i1> {<i2>} . . .)
Equivalent to
(TTYOUT (TALK) (MSG <i1> <i2> . . .))
That is, TTYMSG is identical to MSG, except printed
output is directed to the terminal instead of the
currently selected output device. To insure that the
message will appear on the terminal even if ↑O has been
struck, a TALK is performed before printing. TTYMSG is
compiled in-line.
RUTGERS/UCI LISP MANUAL Page 21
(PRINA @<x> {@<pos>})
Like PRIN1, except if an atom won't fit on the line, a
tab to position <pos> on the next line is performed
before printing resumes. <pos> is optional, with a value
of 1 assumed if omitted.
(PRINAC @<x> {@<pos>})
Identical to PRINA, except PRINC is used to print atoms
instead of PRIN1.
(SPACES @<n>)
Prints <n> spaces. If <n> spaces won't fit on the
current line, SPACES performs a TERPRI instead.
(LINES @<n>)
Prints <n> blank lines. Note that the next print
position will always be at the start of a line, so
(LINES 0) may be used as a "conditional TERPRI" which
outputs a carriage return if not already at the start of
a line.
(PRINL @<l>)
Prints the list <l> without the outermost parentheses,
i.e., prints the elements of <l> separated by spaces.
Each element is printed using PRINA, with a <pos> of 1.
(PRINLC @<l>)
Identical to PRINL, except uses PRINAC instead of PRINA
to print the list elements.
(PRINTC @<x>)
Identical to PRINT, except uses PRINC instead of PRIN1.
(DPRINT @<x>)
Prints <x> with BASE set to 10 (decimal).
(TALK)
Undoes the effect of a previous ↑O. May be used to
insure that a message will appear on the terminal (see
TTYMSG). Note that a TALK is automatically performed by
the system whenever an error condition is encountered or
a prompt character is output.
RUTGERS/UCI LISP MANUAL Page 22
(OUTCH)
Returns the name of the currently selected output channel
(NIL if the TTY).
New Input Functions
←←←←←←←←←←←←←←←←←←←
(TTYIN <e1> {<e2>} . . .)
TTYIN may be used to request input from the terminal
instead of the currently selected input device. The
current channel is deselected, the TTY is selected and
the <e>s are evaluated (hopefully doing some input). The
previous channel is then reselected, and the value of
<en> is returned as the value of the TTYIN. TTYIN is
compiled in-line.
(READL)
Identical to (LINEREAD). READL is (in some sense) the
inverse of PRINL.
(PEEKC)
Returns the ASCII code of the next character in the input
stream without reading the character. Equivalent to
(UNTYI (TYI)).
(DELIM @<char>)
Returns T if the character whose ASCII code is <char> is
a delimiter (i.e., will stop the formation of an atomic
symbol), and NIL if it isn't. For example,
(DELIM (PEEKC)) checks if the next character in the input
stream will be a delimiter.
(CURRCOL)
Returns the number of the next available print position.
(INCH)
Returns the name of the currently selected input channel
(NIL if the TTY).
RUTGERS/UCI LISP MANUAL Page 23
V. NEW DEBUGGING FACILITIES
←←←←←←←←←←←←←←←←←←←←←←←←←←←
Additions to the Editor
←←←←←←←←←←←←←←←←←←←←←←←
LASTWORD
LASTWORD is the variable used by EDITF, EDITV, and EDITP
to obtain a name when none is given explicitly. It
should be noted that in addition to the editor, this
variable is now set and referenced by other program
development modules, including the functions DE, DF, DM,
PP, BREAK, and TRACE. Thus (EDITF) will edit the
function last referenced by any of these functions.
←←←
(EDITEXPR @<expr>)
If <expr> is an atom EDITEXPR simply returns <expr>;
otherwise the editor is called with <expr> as the object
to be edited.
PP* Command
Prettyprints the current edit expression with COMMENTFLG
set to T.
F, BF Commands
The F and BF commands now save their arguments from one
call to the next; if used without an argument the
previous F or BF pattern is used. Note also that strings
may now be found (or replaced) if desired.
FP, BFP Commands
FP and BFP are equivalent to F and BF followed by a P
(Print). They also save their find patterns from one
call to the next.
Additions to the Break Package
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
LASTWORD
As mentioned above, (BREAK) and (TRACE) may be used to
break or trace the function last defined, edited, or
prettyprinted (or broken or traced, if a subsequent
UNBREAK or UNTRACE was performed). Note that BREAK and
TRACE set LASTWORD only for "simple" breaks or traces -
complex conditional breaks, breaks inside of other
functions, etc., do not change LASTWORD.
RUTGERS/UCI LISP MANUAL Page 24
BREAK and TRACE of Compiled Functions
When breaking or tracing compiled functions, the argument
lists supplied by the user are now saved from one call to
the next, so they need only be supplied once for each
function. The argument list is stored on the property
list of the function name under the property ARGS. A
function which wishes to break a compiled function under
program control without user interaction can thus specify
an argument list by placing it under the ARGS property.
(TRACEV <var1> {<var2>} . . .)
TRACEV provides a value-tracing facility for uncompiled
ILISP code. Each time one of the <var>s has its value
changed via SET or SETQ a message showing the new value
is printed. Note that initial variable bindings in
LAMBDA expressions and PROGs, and variables bound within
compiled functions, will not be traced.
(UNTRACEV {<var1>} {<var2>} . . .)
Each variable <var> will have its value tracing turned
off. Like UNBREAK and UNTRACE, (UNTRACEV T) may be used
to untrace the most recently-traced variable, and
(UNTRACEV) turns off all value tracing.
RUTGERS/UCI LISP MANUAL Page 25
VI. THE LISP PRETTYPRINTER
←←←←←←←←←←←←←←←←←←←←←←←←←←
The ILISP prettyprint package provides a powerful facility
for printing functions in readable form and creating formatted
symbolic files. New capabilities include a "printmacro"
mechanism, three levels of user commenting, and a "prettyprint
command" facility for controlling the printing process.
Basic Functions
←←←←←←←←←←←←←←←
(PP {<a1>} {<a2>} . . .)
(PP replaces the old GRINDEF). If <a> is atomic, each
property of <a> which appears on the list PRETTYPROPS is
printed in readable format. (If no such properties
appear a message to that effect is printed - this message
may be suppressed by setting NOPRETTYPROPS to NIL). Each
non-atomic <a> is simply printed via SPRINT unless its
CAR is defined as a "prettyprint command", in which case
the expression is evaluated (prettyprint commands are
explained further below). <a> may also be a list
consisting of a LAP expression followed by a sequence of
LAP code; such a list will be printed in standard LAP
format. If no <a>s are present, the value of LASTWORD is
used. LASTWORD is also set to the name of the last
function printed. Note that if the value of the atomic
symbol PP is non-NIL and output is being directed to a
device other than the terminal, PP will print the name of
each function printed on the terminal. This feature is
used by DSKOUT to provide feedback about the dump (i.e.,
PP is set to the value of DSKOUT before the prettyprinter
is invoked).
(PPL <var1> {<var2>} . . .)
(PPL replaces the old GRINL). Each <var> should be an
atomic symbol which is bound to a prettyprint list to be
passed on to PP. This prettyprint list may contain
atomic symbols whose properties are to be printed,
prettyprint command expressions, and other expressions
which are to be SPRINTed. Each <var> (except ALLFNS)
which is not already a member of its prettyprint list
will be printed so that if dumping to a file its value
will be restored when the file is subsequently loaded.
The prettyprint list will disappear when the file is
compiled, however (i.e., it will not appear in the LAP
file).
(SPRINT @<expr> @<col>)
SPRINT is the workhorse of the prettyprint package - it
is used by PP and PPL to print <expr>s in pretty form
starting in column <col>. The prettyprinting
RUTGERS/UCI LISP MANUAL Page 26
capabilities of SPRINT may be suppressed by setting the
special variable PRETTYFLG to NIL. In this mode, the
prettyprint package may be used to produce fast, compact
(though not very readable) symbolic dumps.
PRETTYPROPS
←←←←←←←←←←←
(PRETTYPROPS replaces the old GRINPROPS). In its simplest
form, PRETTYPROPS is a list of atomic symbols which gives the
properties which PP is to print. Each atomic argument to PP
which has a property on PRETTYPROPS will be printed as a DEFPROP
expression. Occasionally, however, it is desirable to print
certain properties in something other than DEFPROP format. This
may be accomplished by putting a consed pair of the form
(<prop> . <fn>) onto PRETTYPROPS; when an atom with a <prop>
property is encountered, PP simply prints a carriage return and
calls <fn>. <fn> will be passed three arguments: the atom
currently being PPed, the value stored under the property <prop>,
and the atom <prop> itself. The function can then print anything
it wishes before returning to PP, at which time another carriage
return will be printed. For example, the functions PP-VALUE and
PP-RMACS are provided by the prettyprint package to print VALUE
and READMACRO properties in special form.
PRETTYPROPS is initialized to (SPECIAL EXPR FEXPR MACRO
(VALUE . PP-VALUE) PRINTMACRO (READMACRO . PP-RMACS)).
Prettyprint Commands
←←←←←←←←←←←←←←←←←←←←
Prettyprint commands may be used as arguments to PP or in
PPL prettyprint lists to perform a variety of special formatting
tasks. A prettyprint command is simply an expression whose CAR
is a function name with a non-NIL PPCOM property. Such
expressions are evaluated when encountered by PP, thus providing
a mechanism for "grabbing control" during the prettyprint
process. The user may define his own prettyprint commands, or
may use the following functions supplied by the system. Note
that in addition to appearing as prettyprint commands in PPL
lists, these expressions may be used in other contexts as well.
(*PG*)
Outputs a page eject; may be used to place various
sections of a large symbolic file on different pages.
(F: <fn1> {<fn2>} . . .)
Prettyprints any functional attributes of each <fn>,
ignoring all other properties. Actually, F: simply sets
PRETTYPROPS to (EXPR FEXPR MACRO) and passes its
arguments on to PP, so each <fn> may be anything which
can normally be used as an argument to PP. PRETTYPROPS
is restored after printing is completed.
RUTGERS/UCI LISP MANUAL Page 27
(P: <props> <x1> {<x2>} . . .)
PRETTYPROPS is set to <props>, the <x>s are passed on to
PP, and PRETTYPROPS is restored. For example, F: could
be defined as
(P: (EXPR FEXPR MACRO) <fn1> <fn2> . . .)
(V: <x1> {<x2>} . . .)
Useful for printing values. Each <x> may be either an
atomic symbol <var> or a list of the form (<var> <val>).
Each <var> will be printed as a DEFV expression, with a
value of <val> if given, or the current value of the
variable if only the variable name was given (unbound
variables are printed with a value of NIL).
(MBD: <fn> <x1> {<x2>} . . .)
Passes the <x>s on to PP in such a way that they will be
prettyprinted inside of an expression starting with <fn>.
For example, to prettyprint F1 and F2 inside of a PROGN
expression (perhaps so they will not be compiled) one
could do:
(MBD: PROGN F1 F2)
(FORMS: <x1> {<x2>} . . .)
Each <x> is passed directly to SPRINT - may be used to
print atoms and prettyprint command expressions which
would normally be handled specially by PP.
(E: <e1> {<e2>} . . .)
The <e>s are simply evaluated. For example, the
inclusion of the following in a prettyprint list could be
used to change the base in the middle of a print:
(E: (SETQ BASE 10.))
Printmacros
←←←←←←←←←←←
SPRINT normally operates by formatting the expression being
printed using indentation to produce "pretty" output. It is
occasionally desirable to have certain subexpressions printed in
some special format for increased readability. Such a capability
is provided via the use of printmacros. Any function may be
←←←←←←←←←←←
flagged as a printmacro by placing the macro definition on the
property list of the atom under the indicator PRINTMACRO.
Whenever an atom with such a property appears as the first
element in a list being prettyprinted, SPRINT takes special
action, such action depending on the value of the PRINTMACRO
property:
RUTGERS/UCI LISP MANUAL Page 28
(1) If the value is a string the string is simply PRINCed and the
CADR of the original expression is SPRINTed. This serves as
an inverse for READMACROs of the @<e> -> (QUOTE <e>) type.
For example,
(DEFPROP QUOTE "@" PRINTMACRO)
(DEFPROP THV "$?" PRINTMACRO)
(the QUOTE printmacro is in fact already present in ILISP).
(2) If the value is the special atomic symbol BRACKETS then the
expression is printed by SPRINT in the normal way, except
that each top-level non-atomic argument will be printed with
brackets [...] instead of the usual parentheses (...). This
gives the user one more method of producing more readable
output. COND, SELECTQ, AND, OR, and CATCH are initialized as
printmacros of this type. To disable the use of brackets for
these functions simply REMPROP the PRINTMACRO property from
their property lists.
(3) If the value of the PRINTMACRO property is neither a string
nor the atomic symbol BRACKETS it is assumed to be a true
printmacro function (or, more typically, the name of a
function). This function will be passed the expression being
printed as its only argument, and may print it in any format
it wishes (calling SPRINT recursively if desired). If the
printmacro function decides that the expression should be
printed in normal form by SPRINT (i.e., it is a "conditional"
printmacro), it may simply print nothing and return the
atomic symbol SPRINT. SPRINT will then print the expression
as if no printmacro property were present (note that this
special case is necessitated by the fact that a recursive
call on SPRINT with the original expression would cause the
printmacro function to be reinvoked). If the printmacro
function returns anything else, SPRINT assumes that it has
printed the entire expression, and simply proceeds. As an
example of a printmacro function, one might do the following
in lieu of defining QUOTE as a string printmacro:
(DEFPROP QUOTE
(LAMBDA (E)
(COND [(AND [CONSP (CDR E)] [NULL (CDDR E)])
(PRINC @"@")
(SPRINT (CADR E) (CURRCOL))]
[T @SPRINT]))
PRINTMACRO)
This is in fact what is already done for string printmacros -
the expression is checked to insure that it has only one
argument and, if not, is printed as a normal list.
RUTGERS/UCI LISP MANUAL Page 29
To make the writing of printmacro functions easier several
auxiliary formatting functions are provided:
(PP-FORMAT @<e> @<n> @<flag>)
Prints the expression <e> with the first <n>+1 elements
(the function name and <n> arguments) printed on one
line. <flag> specifies how the remaining arguments are
to be printed: if <flag>=NIL (standard format), all
remaining arguments are printed under the first argument;
if <flag>=MISER, the remaining arguments are placed under
the function name; if <flag>=LABELS, all non-atomic
arguments are printed under the first argument, with
atoms placed to the left as labels. Note, however, that
if the entire expression will fit on one line, and is
less than PP-FORMAT characters long (initially 40), it
will be printed on one line.
(PP-MISER @<e>)
Equivalent to:
(PP-FORMAT @<e> 1 @MISER)
This is the system printmacro function used for LAMBDA
and DEFPROP.
(PP-MISER0 @<e>)
Equivalent to:
(PP-FORMAT @<e> 0 @MISER)
This is the system printmacro function used for FUNCTION
and *FUNCTION.
(PP-LABELS @<e>)
Equivalent to:
(PP-FORMAT @<e> 1 @LABELS)
This is the system printmacro function used for PROG.
Comments
←←←←←←←←
One of the major disadvantages of many LISP systems is the
lack of a usable commenting facility. This has been remedied in
ILISP by the addition of three levels of comments: *, **, and
***. These atoms are defined as macros which expand to NIL;
expressions starting with *, **, or *** may be placed in function
definitions anywhere a NIL could be placed without harm, e.g., at
the top level of LAMBDAs and PROGs (when the function is
subsequently compiled, these expressions will disappear). *, **,
RUTGERS/UCI LISP MANUAL Page 30
and *** are also defined as printmacros which cause the
expression to be printed in block form as a comment. * comments
are intended to be used for detailed descriptions of code - they
are printed starting in column 40. ** comments are intended to
serve as top-level descriptions of functions - they are printed
starting in column 10. *** comments are intended to be used in
prettyprint lists to describe major sections of a symbolic file
(perhaps following a (*PG*) prettyprint command) - they are
printed starting in column 1.
Recall that the E: prettyprint command may be used to cause
expressions to be evaluated before printing a certain function.
It is also possible to cause an expression to be evaluated while
←←←←←
a function is being prettyprinted. This is done by placing the
atomic symbol E as the second element of a comment, and the
expression to be evaluated as the third element. For example,
the comment
(* E (SETQ BASE 10.) Changing base)
changes the base at prettyprint time.
Comment atoms are flagged by placing the function name
PP-COMMENT on the property list of the atom under the PRINTMACRO
property, and putting the desired starting print column on the
property list under the property COMMENT. The user may thus
disable *, **, and/or *** as comment atoms by removing these two
properties, or may change the starting column or add new comment
atoms if desired.
Note that comments are intended primarily to comment
symbolic files - when printing to the terminal all comments
appear simply as *COMMENT* unless the special variable COMMENTFLG
is non-NIL. The functions PP* and PPL*, and the edit command
PP*, may be used to print function definitions with comments on
the terminal (i.e., they first set COMMENTFLG to T).
Note also that comments are treated by LISP as normal list
structures, and hence must obey all LISP syntax rules. In
particular, this means that periods may not be used and commas
will disappear. It is suggested that ";" be used instead of
period as a terminator as it is not a LISP punctuation mark and
thus simply becomes part of an atomic symbol.
RUTGERS/UCI LISP MANUAL Page 31
VII. THE COMPILER AND LAP
←←←←←←←←←←←←←←←←←←←←←←←←←
The ILISP compiler (ILISPC) is an extended (and debugged)
version of the Stanford LISP 1.6 compiler. As before, a file of
LISP functions is compiled via the function COMPL, which takes a
file specification (like DSKIN) and creates a LAP file which can
subsequently be loaded via DSKIN.
Declarations
←←←←←←←←←←←←
Although the use of the compiler is quite straightforward,
there are several declarations which can (and sometimes must) be
made to give the compiler additional information about your code.
These declarations should appear at the beginning of the file
inside a DECLARE expression:
(DECLARE <d1> {<d2>} . . .)
Each <d> is a compiler declaration expression - such
declarations are ignored when the file containing the
DECLARE is loaded, but are evaluated when the file is
compiled. Available declarations are given below.
(SPECIAL <var1> {<var2>} . . .)
Declares each <var> as a special variable, i.e., a
variable which appears free in a function. Note that
free variables in in-line LAMBDA expressions and LAMBDA
expressions used as arguments to most system functions
(e.g., the MAP functions) need not be declared SPECIAL,
as such functions are compiled in-line. In addition
ERRSETs are now compiled in-line, so variables in ERRSET
expressions no longer have to be declared SPECIAL. All
undeclared free variables in a file may be found by
compiling the file and examining the error messages; for
convenience, the compiler places all newly-discovered
special variables on the list SPECIALS.
(UNSPECIAL <var1> {<var2>} . . .)
This declaration may be used to inform the compiler that
certain variables are no longer considered special, and
should be compiled as normal local variables in
subsequent functions.
(NOCALL <a1> {<a2>} . . .)
Each <a> should be either the name of a function to be
compiled or a special variable. These functions and
variables are assumed to be local to the file being
compiled and will thus never be traced, called or
referenced from functions not in this file, or used as
entry points or top-level values. The compiler can
RUTGERS/UCI LISP MANUAL Page 32
compile references to such functions as direct jumps, and
the atoms may be REMOBed when the file is loaded (see
DUMPATOMS below). It is also possible to cause all
←←←
function references to be changed to direct jumps when a
LAP file is loaded (see below).
(CALL <fn1> {<fn2>} . . .)
Specifies that each <fn> should always be called via the
←←←←←←
function-calling mechanism and not changed to direct
jumps. Necessary in rare cases when the new NOCALL=T
feature is being used (see below for further
explanation).
(GLOBALMACRO <mac1> {<mac2>} . . .)
Macro definitions are normally assumed to be used only by
functions in the file in which they appear, and hence are
not necessary after the file is compiled. Occassionally,
however, it is desirable to keep the macro definitions
after compilation by having them copied into the LAP file
(PLUS is such a macro for example). The GLOBALMACRO
declaration specifies that each <mac> is such a global
macro and should be saved.
(*SUBR/*FSUBR/*LSUBR <fn1> {<fn2>} . . .)
FSUBRs and LSUBRs which are referenced before they are
compiled must be declared (via *FSUBR and *LSUBR) so that
the compiler can compile function references correctly.
*SUBR declarations may also be made, although they are
normally not necessary since all undefined functions are
assumed to be SUBRs. The only exception is when a
function name is also used as a variable - it then must
be declared if it is referenced before it is compiled.
*EXPR, *FEXPR, and *LEXPR may be used in place of *SUBR,
*FSUBR, and *LSUBR if desired.
Extensions to NOCALL
←←←←←←←←←←←←←←←←←←←←
As stated above, NOCALL declarations are intended to flag
atomic symbols (both functions and, in the Rutgers ILISP system,
special variables) which are not necessary after a LAP file is
loaded and may thus be REMOBed (only the special cell of a
variable is actually referenced by compiled code). In order to
make this process reversible, the following function is now
provided:
(DUMPATOMS {<file>})
After loading a set of files which contain NOCALL
declarations, DUMPATOMS may be called to REMOB all NOCALL
atoms after first creating a file <file> which, when
subsequently loaded, will restore the SUBR, FSUBR, LSUBR,
RUTGERS/UCI LISP MANUAL Page 33
VALUE, and SYM properties of each NOCALL atom. One can
thus use DUMPATOMS to REMOB all NOCALL atoms (to save
space), and if it is later discovered that one of the
functions or special variables is needed after all, DSKIN
the DUMPATOMS file to restore things to their previous
state. If <file> is missing, (REMOB.LSP) is assumed.
In addition to saving space by allowing unnecessary atomic
symbols to be REMOBed, NOCALL declarations provide for faster
execution by replacing function calls with direct jumps. It is
now possible to cause all function calls to be loaded as direct
←←←
jumps by setting NOCALL to T before loading the relevant files
(it should be set back to NIL after loading is completed). Note
that this should be done only after all functions are completely
debugged, as none of the functions can be traced or redefined
after loading. Specific functions may be exempted from this
inclusive NOCALL by declaring them CALL at compile time (see
above). This is optional in some cases (e.g., one wants to be
able to trace a particular function), and necessary in others.
In particular, any function which is listed as "undefined" at
compile time must be declared CALL unless a compiled version of
the function will later be loaded along with the LAP file.
Note that when loading LAP files with NOCALL=T all functions
are assumed to be either already defined when the files are
loaded (e.g., system functions), or defined in the LAP files. If
any existing compiled functions (such as system functions) are to
be redefined, they must either be defined before they are
referenced or must have their SUBR, FSUBR, or LSUBR properties
removed before loading. LAP keeps track of any previously
defined functions which are called via direct jumps (after
loading is complete the value of NOCALL will be a list of such
functions), and a warning message is printed if such a function
is redefined.
In-Line Code
←←←←←←←←←←←←
A number of system functions are compiled in-line by the
compiler, either because they generate only a few words of code
or because they are FEXPRs which evaluate one or more arguments
(if calls to such functions were not compiled in-line, the
uncompiled arguments would be passed to the interpreter, slowing
down execution considerably). Functions currently compiled
in-line include:
ERRSET, CATCH, THROW, RPTQ, COND, AND, OR, SELECTQ,
PROG1, PROG2, PROGN (and DO), PROG, RETURN, GO, SETQ,
MSG, TTYMSG, TTYIN, TTYOUT, SUBSET, EVERY, SOME, NOTANY,
NOTEVERY, All Map Functions, APPEND (as *APPENDs), NCONC
(as *NCONCs), LIST (as CONSes), CAR, CDR, RPLACA, RPLACD,
EQ, NEQ, NULL (and NOT), ZEROP, ARG, SETARG, STORE, EVAL
(as *EVAL or a direct call if possible), APPLY (as *APPLY
or a direct call if possible), and APPLY# (as a direct
call if possible).
RUTGERS/UCI LISP MANUAL Page 34
Other Extensions
←←←←←←←←←←←←←←←←
The compiler normally works by compiling all function
definitions in the file (putting the compiled code in the LAP
file), and copying all other expressions into the LAP file
unchanged (except for comments and DECLARE expressions). It is
sometimes desirable to change this standard convention. For
example, the GLOBALMACRO declaration causes macros to be used by
the compiler and also copied to the LAP file. Certain functions
may have their compilation suppressed (with the symbolic
definition copied to the LAP file) by placing their definitions
inside a PROGN (the MBD: prettyprint command is useful for
this). A new capability is now available which allows certain
expressions to be evaluated when the symbolic file is loaded, but
to not be copied to the LAP file. This is accomplished by
placing the expressions inside a NOCOMPILE (which acts like a
PROGN when evaluated). For example, the prettyprint package
causes PPL prettyprint lists to disappear at compile time by
placing the variable binding inside a NOCOMPILE expression.
Recall that strings are normally not interned by the READ
routine so that they will be garbage collected when no longer
referenced. Strings appearing in compiled code will always be
referenced, however, so LAP has been modified to intern them (by
setting INTERNSTR to T). This has the advantage that functions
which are compiled may reference the same string a number of
times without penalty - only one copy will be stored.
The compiler now prints the name of each function before its
compilation has begun. If an error occurs, the last name printed
is the function in error. Note also that the value returned by
LAP (and thus printed by DSKIN) is now a list consisting of the
name of the function loaded followed by the number of words of
binary program space required for the compiled code.
LAP maintains several global lists which the naive user
should leave alone: LAPLST is used by the break package for
associating variable names with special cells; LAPKLST (formerly
KLIST) is used by LAP in order to reuse constants within compiled
code; LAPQLST (formerly QLIST) is used in an attempt to reuse
quoted expressions referenced from compiled code, and to make
them known to the garbage collector; and LAPSLST is a list of
special cells of NOCALL variables for use by the garbage
collector.
RUTGERS/UCI LISP MANUAL Page 35
VIII. INFORMATION FOR THE SYSTEM BUILDER
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
User Error Handling
←←←←←←←←←←←←←←←←←←←
Recall that errors currently cause a message to be printed
and a break to the break package to occur (unless an ERRSET is
suppressing error messages or the break package has been turned
off via (*RSET NIL)). The user now has the capability to grab
control whenever an error is encountered by setting USERERRORX to
the name of an error-handling function. If the user error
handler returns NIL the system break package is entered, giving
the user the ability to examine the form which caused the error
(it is on the stack) and conditionally break to the break
package. Otherwise it is assumed that the user error handler
will process the error and either return a non-NIL value to
continue the computation or restart at some other point. Note
that the user error function should be a function of one
argument, which in most cases should be ignored (it is an
indication as to whether ILISP considers the error a "serious"
error (T) or a "correctable" error (NIL); error messages for
correctable errors may be suppressed via (*RSET @ERRORX)).
Creating One's Own System
←←←←←←←←←←←←←←←←←←←←←←←←←
Most users who create their own ILISP-based system will want
to save only the low segment of their core image, with ILISP's
sharable high segment loaded at run time. This may be
accomplished by exiting from ILISP via (EXIT NIL), which removes
the high segment so that SAVE will create only a SAV (low
segment) file instead of LOW and HGH files. When such a SAV file
is later RUN, ILISP's standard sharable high segment will
automatically be loaded. Note that an EXCISE or a SYSCLR should
always be done before exiting and saving ILISP - if this is not
done the I/O buffers will be allocated as available space,
causing the ALLOC? message to appear each time the saved program
is run.
Although it is suggested that most ILISP-based systems share
the standard ILISP high segment as outlined above (ILISPC, FUZZY,
etc. are of this type), it may be desirable that a heavily-used
system with large amounts of compiled code have its own sharable
high segment. In order to do this one must have write privileges
for the system (see discussion under SETSYS in the UCI LISP
manual), and must execute a HGHCOR to allocate space for compiled
code in the high segment. The compiled code may then be loaded
via the new function HGHIN, which is identical to DSKIN except
compiled code is placed in the high segment. The following
summarizes the procedure necessary to create a sharable system:
RUTGERS/UCI LISP MANUAL Page 36
.R ILISP
*(SETSYS (<proj>,<prog>) <name of system>)
*(EXIT T)
.SSA <name of system>
.RU <name of system>
*(HGHCOR <# of words of compiled code>)
*(REALLOC <other space allocations> . . .)
*(SETQ NOCALL T)
*(HGHIN <your files>)
*(SETQ NOCALL NIL)
*(SYSCLR)
*(INITFN @<fn to print header>)
*(EXIT T)
.SSA <name of system>
Building ILISP
←←←←←←←←←←←←←←
The files ILISP.CTL, ILISPC.CTL, PLNR.CTL, CNVR.CTL, and
FUZZY.CTL are DOER control files which may be used for building
the various ILISP modules. They should be consulted if any of
these systems need to be reconstructed. After constructing the
various modules, the following files should be copied into SYS:
ILISP.LOW
ILISP.SHR
ILISP.LOD
ILISP.SYM
ILISPC.SAV
PLNR.SAV (if desired)
CNVR.SAV (if desired)
FUZZY.SAV (if desired)
RUTGERS/UCI LISP MANUAL Page 37
INDEX
←←←←←
%DEVP . . . . . . . . . . . . . . . . . . . . . 19
* . . . . . . . . . . . . . . . . . . . . . . . 29
** . . . . . . . . . . . . . . . . . . . . . . . 29
*** . . . . . . . . . . . . . . . . . . . . . . 29
*APPLY . . . . . . . . . . . . . . . . . . . . . 11
*FSUBR (or *FEXPR) . . . . . . . . . . . . . . . 32
*INSERT . . . . . . . . . . . . . . . . . . . . 14
*LSUBR (or *LEXPR) . . . . . . . . . . . . . . . 32
*MERGE . . . . . . . . . . . . . . . . . . . . . 14-15
*NCONC . . . . . . . . . . . . . . . . . . . . . 15
*NOPOINT . . . . . . . . . . . . . . . . . . . . 17
*NOPOINTDSK . . . . . . . . . . . . . . . . . . 17
*PG* . . . . . . . . . . . . . . . . . . . . . . 26, 30
*SORT . . . . . . . . . . . . . . . . . . . . . 15
*SUBR (or *EXPR) . . . . . . . . . . . . . . . . 32
ADDPROP . . . . . . . . . . . . . . . . . . . . 12
ALLFNS . . . . . . . . . . . . . . . . . . . . . 7
APPLY (Funarg Argument) . . . . . . . . . . . . 10
ARGS . . . . . . . . . . . . . . . . . . . . . . 24
ATOM . . . . . . . . . . . . . . . . . . . . . . 10
ATTACH . . . . . . . . . . . . . . . . . . . . . 16
BASE (With Negative Value) . . . . . . . . . . . 17
BF (Edit Command) . . . . . . . . . . . . . . . 23
BFP (Edit Command) . . . . . . . . . . . . . . . 23
BOUNDP . . . . . . . . . . . . . . . . . . . . . 11
BRACKETS . . . . . . . . . . . . . . . . . . . . 28
BREAK . . . . . . . . . . . . . . . . . . . . . 7, 23-24
CALL . . . . . . . . . . . . . . . . . . . . . . 32-33
CATCH . . . . . . . . . . . . . . . . . . . . . 10-11
COMMENT . . . . . . . . . . . . . . . . . . . . 30
COMMENTFLG . . . . . . . . . . . . . . . . . . . 23, 30
COMPL . . . . . . . . . . . . . . . . . . . . . 31
CONSP . . . . . . . . . . . . . . . . . . . . . 10
CONTINUE (Monitor Command) . . . . . . . . . . . 5
CURRCOL . . . . . . . . . . . . . . . . . . . . 22
DATE . . . . . . . . . . . . . . . . . . . . . . 9
DE . . . . . . . . . . . . . . . . . . . . . . . 7, 23
DECLARE . . . . . . . . . . . . . . . . . . . . 31
DEFLIST . . . . . . . . . . . . . . . . . . . . 12
DEFP . . . . . . . . . . . . . . . . . . . . . . 12
DEFV . . . . . . . . . . . . . . . . . . . . . . 12
DELIM . . . . . . . . . . . . . . . . . . . . . 22
DF . . . . . . . . . . . . . . . . . . . . . . . 7, 23
DIRF . . . . . . . . . . . . . . . . . . . . . . 19
DM . . . . . . . . . . . . . . . . . . . . . . . 7, 23
DO . . . . . . . . . . . . . . . . . . . . . . . 11
DPRINT . . . . . . . . . . . . . . . . . . . . . 21
DSKIN (Printing Control) . . . . . . . . . . . . 18
DSKLENGTH . . . . . . . . . . . . . . . . . . . 18
DSKOUT . . . . . . . . . . . . . . . . . . . . . 18, 25
DTIME . . . . . . . . . . . . . . . . . . . . . 9
DUMPATOMS . . . . . . . . . . . . . . . . . . . 32
E: . . . . . . . . . . . . . . . . . . . . . . . 27, 30
EDITCH . . . . . . . . . . . . . . . . . . . . . 6
EDITEXPR . . . . . . . . . . . . . . . . . . . . 23
EDITF . . . . . . . . . . . . . . . . . . . . . 7, 23
EDITP . . . . . . . . . . . . . . . . . . . . . 7, 23
EDITV . . . . . . . . . . . . . . . . . . . . . 7, 23
ENTER . . . . . . . . . . . . . . . . . . . . . 12, 15
EQSTR . . . . . . . . . . . . . . . . . . . . . 16
ERRCH . . . . . . . . . . . . . . . . . . . . . 6
ERRSET (Compiled In-line) . . . . . . . . . . . 31
EVAL (Funarg Argument) . . . . . . . . . . . . . 10
EVERY . . . . . . . . . . . . . . . . . . . . . 13
EXIT . . . . . . . . . . . . . . . . . . . . . . 5-6, 8
EXPBPS . . . . . . . . . . . . . . . . . . . . . 8
EXPFS . . . . . . . . . . . . . . . . . . . . . 8
EXPFWS . . . . . . . . . . . . . . . . . . . . . 8
F (Edit Command) . . . . . . . . . . . . . . . . 23
F: . . . . . . . . . . . . . . . . . . . . . . . 26
FILBAK . . . . . . . . . . . . . . . . . . . . . 18
FORMS: . . . . . . . . . . . . . . . . . . . . . 27
FP (Edit Command) . . . . . . . . . . . . . . . 23
FSCNT . . . . . . . . . . . . . . . . . . . . . 9
Funarg Pointers . . . . . . . . . . . . . . . . 10
FWCNT . . . . . . . . . . . . . . . . . . . . . 9
GETDEF . . . . . . . . . . . . . . . . . . . . . 18-19
GLOBALMACRO . . . . . . . . . . . . . . . . . . 32
HGHIN . . . . . . . . . . . . . . . . . . . . . 35
INCH . . . . . . . . . . . . . . . . . . . . . . 22
INSERT . . . . . . . . . . . . . . . . . . . . . 14
INTERNSTR . . . . . . . . . . . . . . . . . . . 17, 34
INTERSECTION . . . . . . . . . . . . . . . . . . 15
KLIST (Changed to LAPKLST) . . . . . . . . . . . 34
LAP . . . . . . . . . . . . . . . . . . . . . . 17, 25, 31-34
LAPKLST . . . . . . . . . . . . . . . . . . . . 34
LAPLST . . . . . . . . . . . . . . . . . . . . . 34
LAPQLST . . . . . . . . . . . . . . . . . . . . 34
LAPSLST . . . . . . . . . . . . . . . . . . . . 34
LASTWORD . . . . . . . . . . . . . . . . . . . . 7, 23, 25
LEXORDERCAR . . . . . . . . . . . . . . . . . . 14-15
LINEREAD . . . . . . . . . . . . . . . . . . . . 22
LINES . . . . . . . . . . . . . . . . . . . . . 21
LOAD (Aborted by ↑C) . . . . . . . . . . . . . . 5
LPTLENGTH (Identical to DSKLENGTH) . . . . . . . 18
MAPATOMS . . . . . . . . . . . . . . . . . . . . 13
MBD: . . . . . . . . . . . . . . . . . . . . . . 27, 34
MCONS . . . . . . . . . . . . . . . . . . . . . 16
MEMBFN . . . . . . . . . . . . . . . . . . . . . 12, 15
MERGE . . . . . . . . . . . . . . . . . . . . . 15
MODCHR (Interaction with PRINT) . . . . . . . . 18
MSG . . . . . . . . . . . . . . . . . . . . . . 20
NCONC1 . . . . . . . . . . . . . . . . . . . . . 16
NIL (CAR and CDR = NIL) . . . . . . . . . . . . 10
NOCALL . . . . . . . . . . . . . . . . . . . . . 31-33
NOCOMPILE . . . . . . . . . . . . . . . . . . . 34
NOPRETTYPROPS . . . . . . . . . . . . . . . . . 25
NOTANY . . . . . . . . . . . . . . . . . . . . . 14
NOTEVERY . . . . . . . . . . . . . . . . . . . . 14
OUTCH . . . . . . . . . . . . . . . . . . . . . 22
P: . . . . . . . . . . . . . . . . . . . . . . . 27
PATOM . . . . . . . . . . . . . . . . . . . . . 10
PEEKC . . . . . . . . . . . . . . . . . . . . . 22
PP . . . . . . . . . . . . . . . . . . . . . . . 7, 23, 25
PP* . . . . . . . . . . . . . . . . . . . . . . 30
PP* (Edit Command) . . . . . . . . . . . . . . . 23, 30
PP-COMMENT . . . . . . . . . . . . . . . . . . . 30
PP-FORMAT . . . . . . . . . . . . . . . . . . . 29
PP-LABELS . . . . . . . . . . . . . . . . . . . 29
PP-MISER . . . . . . . . . . . . . . . . . . . . 29
PP-MISER0 . . . . . . . . . . . . . . . . . . . 29
PPCOM . . . . . . . . . . . . . . . . . . . . . 26
PPL . . . . . . . . . . . . . . . . . . . . . . 25
PPL* . . . . . . . . . . . . . . . . . . . . . . 30
PRETTYPROPS . . . . . . . . . . . . . . . . . . 25-26
PRINA . . . . . . . . . . . . . . . . . . . . . 20-21
PRINAC . . . . . . . . . . . . . . . . . . . . . 20-21
PRINL . . . . . . . . . . . . . . . . . . . . . 21
PRINLC . . . . . . . . . . . . . . . . . . . . . 21
PRINTC . . . . . . . . . . . . . . . . . . . . . 21
PRINTMACRO . . . . . . . . . . . . . . . . . . . 27
PUT . . . . . . . . . . . . . . . . . . . . . . 13
PUTLIST . . . . . . . . . . . . . . . . . . . . 13
Q (The Octal Point) . . . . . . . . . . . . . . 17
QLIST (Changed to LAPQLST) . . . . . . . . . . . 34
RAISE . . . . . . . . . . . . . . . . . . . . . 7
READL . . . . . . . . . . . . . . . . . . . . . 22
REALLOC . . . . . . . . . . . . . . . . . . . . 8
REENTER (Monitor Command) . . . . . . . . . . . 5-6
REMLIST . . . . . . . . . . . . . . . . . . . . 13
REMPROPS . . . . . . . . . . . . . . . . . . . . 13
REREADCH . . . . . . . . . . . . . . . . . . . . 6
RPTN . . . . . . . . . . . . . . . . . . . . . . 11
RPTQ . . . . . . . . . . . . . . . . . . . . . . 11
SOME . . . . . . . . . . . . . . . . . . . . . . 13
SORT . . . . . . . . . . . . . . . . . . . . . . 15
SPACES . . . . . . . . . . . . . . . . . . . . . 21
SPDL Pointers . . . . . . . . . . . . . . . . . 10
SPECIAL . . . . . . . . . . . . . . . . . . . . 31
SPECIALS . . . . . . . . . . . . . . . . . . . . 31
SPRINT . . . . . . . . . . . . . . . . . . . . . 25, 27-28
START (Monitor Command) . . . . . . . . . . . . 5-6
SUBSET . . . . . . . . . . . . . . . . . . . . . 14
SUBSTRING . . . . . . . . . . . . . . . . . . . 16
TALK . . . . . . . . . . . . . . . . . . . . . . 20-21
THROW . . . . . . . . . . . . . . . . . . . . . 10-11
TIMER . . . . . . . . . . . . . . . . . . . . . 9
TRACE . . . . . . . . . . . . . . . . . . . . . 7, 23-24
TRACEV . . . . . . . . . . . . . . . . . . . . . 24
TTYIN . . . . . . . . . . . . . . . . . . . . . 22
TTYMSG . . . . . . . . . . . . . . . . . . . . . 20
TTYOUT . . . . . . . . . . . . . . . . . . . . . 20
TYPE . . . . . . . . . . . . . . . . . . . . . . 19
UNION . . . . . . . . . . . . . . . . . . . . . 15
UNSAVE . . . . . . . . . . . . . . . . . . . . . 7
UNSPECIAL . . . . . . . . . . . . . . . . . . . 31
UNTRACEV . . . . . . . . . . . . . . . . . . . . 24
USERERRORX . . . . . . . . . . . . . . . . . . . 35
V: . . . . . . . . . . . . . . . . . . . . . . . 27
↑C . . . . . . . . . . . . . . . . . . . . . . . 5-6
↑D . . . . . . . . . . . . . . . . . . . . . . . 5
↑F . . . . . . . . . . . . . . . . . . . . . . . 6
↑G . . . . . . . . . . . . . . . . . . . . . . . 6
↑H . . . . . . . . . . . . . . . . . . . . . . . 6
↑O . . . . . . . . . . . . . . . . . . . . . . . 9, 20-21
↑R . . . . . . . . . . . . . . . . . . . . . . . 6
↑U . . . . . . . . . . . . . . . . . . . . . . . 6
↑X . . . . . . . . . . . . . . . . . . . . . . . 5-6, 8
↑Z . . . . . . . . . . . . . . . . . . . . . . . 6